﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using AI3SaveEditor.AI3Files;
using Microsoft.Win32;
using System.Threading;

namespace AI3SaveEditor
{
    public partial class MainForm : Form
    {
        public static string saveFolder;


        private ListView listView {
            get {
                if (tabControl.SelectedTab == tbGirls) {
                    return lvGirls;
                }
                else if (tabControl.SelectedTab == tbClothes) {
                    return lvClothes;
                }
                else throw new ApplicationException();
            }
        }

        private PropertyGrid propertyGrid {
            get {
                if (tabControl.SelectedTab == tbGirls) {
                    return pgGirl;
                }
                else if (tabControl.SelectedTab == tbClothes) {
                    return pgClothes;
                }
                else throw new ApplicationException();
            }
        }

        public MainForm() {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e) {
            this.Text = Application.ProductName;
            InitControls();
            LoadFolder();
            RefreshGirls();
            RefreshClothes();
            lvClothes.ListViewItemSorter = new ListViewColumnSorter();
            lvGirls.ListViewItemSorter = new ListViewColumnSorter();
            lvClothes.ColumnClick += new ColumnClickEventHandler(ListViewHelper.ListView_ColumnClick);
            lvGirls.ColumnClick += new ColumnClickEventHandler(ListViewHelper.ListView_ColumnClick);
            RefreshInfos();
        }

        private void InitControls() {
            foreach (var each in Enum.GetValues(typeof(View))) {
                cboViewType.Items.Add(each);
            }
            cboViewType.SelectedItem = View.Details;
        }

        private void LoadFolder() {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\illusion\JS3", false);
            if (key != null) {
                saveFolder = Path.GetFullPath(PathHelper.Combine((string)key.GetValue("INSTALLDIR"), "data", "save"));
            }
            else {
                Program.Message("使用前请先运行AI3注册表补丁");
                Application.Exit();
            }
        }

        private void RefreshGirls() {
            lvGirls.Items.Clear();
            Image image = null;
            DirectoryInfo folder = new DirectoryInfo(Path.Combine(saveFolder, @"m_cha"));

            foreach (var each in folder.GetFiles("*.js3cmi")) {
                string js3csiFile = PathHelper.Combine(folder.FullName, Path.GetFileNameWithoutExtension(each.Name), Path.GetFileNameWithoutExtension(each.Name) + ".js3csi");
                if (!File.Exists(js3csiFile))
                    continue;
                GirlProfile file = (GirlProfile)AI3File.Load(each.FullName);
                string imageFile = Path.Combine(each.DirectoryName, Path.GetFileNameWithoutExtension(each.Name) + "_v.bmp");
                image = File.Exists(imageFile) ? Image.FromFile(imageFile) : global::AI3SaveEditor.Properties.Resources.no_priview;
                girlsImage.Images.Add(image);

                ListViewItem item = lvGirls.Items.Add(Path.GetFileNameWithoutExtension(each.Name));
                item.SubItems.Add(file.FirstName);
                item.SubItems.Add(file.LastName);
                item.SubItems.Add(file.LastWriteTime.ToString("yyyy-MM-dd hh:mm"));
                item.ImageIndex = item.Index;
                item.Tag = file;

            }
            foreach (DirectoryInfo info in folder.GetDirectories()) {
                string js3csiFile = Path.Combine(info.FullName, info.Name + ".js3csi");
                if (!File.Exists(info.FullName + ".js3cmi") && File.Exists(js3csiFile)) {
                    GirlProfile file = (GirlProfile)AI3File.Load(js3csiFile);
                    image = File.Exists(info.FullName + "_v.bmp") ? Image.FromFile(info.FullName + "_v.bmp") : global::AI3SaveEditor.Properties.Resources.no_priview;
                    girlsImage.Images.Add(image);

                    ListViewItem item = lvGirls.Items.Add(info.Name);
                    item.SubItems.Add(file.FirstName);
                    item.SubItems.Add(file.LastName);
                    item.SubItems.Add(file.LastWriteTime.ToString("yyyy-MM-dd hh:mm"));
                    item.ImageIndex = item.Index;
                    item.Tag = file;
                }
            }


        }

        private void RefreshClothes() {
            lvClothes.Items.Clear();
            Image image = null;
            DirectoryInfo folder = new DirectoryInfo(Path.Combine(saveFolder, @"m_cos"));
            FileInfo[] files = folder.GetFiles("*.js3fmi");

            ProgressForm progress = new ProgressForm(files.Length, "加载服装", "正在加载服装");

            foreach (var each in files) {
                string fileName = Path.GetFileNameWithoutExtension(each.Name);
                progress.UpdateMessage(each.Name);
                string js3fsiFile = PathHelper.Combine(folder.FullName, fileName, Path.GetFileNameWithoutExtension(each.Name) + ".js3fsi");
                if (!File.Exists(js3fsiFile))
                    continue;

                ClothesFile file = (ClothesFile)AI3File.Load(each.FullName);
                string imageFile = Path.Combine(each.DirectoryName, fileName + "_v.bmp");
                image = File.Exists(imageFile) ? Image.FromFile(imageFile) : global::AI3SaveEditor.Properties.Resources.no_priview;
                clothesImage.Images.Add(image);

                ListViewItem item = lvClothes.Items.Add(Path.GetFileNameWithoutExtension(file.Name));
                item.SubItems.Add(each.Name);
                item.SubItems.Add(each.LastWriteTime.ToString("yyyy-MM-dd hh:mm"));
                item.ImageIndex = item.Index;
                item.Tag = file;
            }
            progress.Close();
            foreach (DirectoryInfo info in folder.GetDirectories()) {
                string js3csiFile = Path.Combine(info.FullName, info.Name + ".js3fsi");
                if (!File.Exists(info.FullName + ".js3fmi") && File.Exists(js3csiFile)) {
                    ClothesFile file = (ClothesFile)AI3File.Load(js3csiFile);
                    image = File.Exists(info.FullName + "_v.bmp") ? Image.FromFile(info.FullName + "_v.bmp") : global::AI3SaveEditor.Properties.Resources.no_priview;
                    clothesImage.Images.Add(image);

                    ListViewItem item = lvClothes.Items.Add(file.Name);
                    item.BackColor = Color.LightCoral;
                    item.SubItems.Add(info.Name);
                    item.SubItems.Add(file.LastWriteTime.ToString("yyyy-MM-dd hh:mm"));
                    item.ImageIndex = item.Index;
                    item.Tag = file;
                }
            }
        }

        private void UpdateListViewItem(ListViewItem item) {
            if (item.Tag is GirlProfile) {
                GirlProfile file = item.Tag as GirlProfile;
                item.SubItems[1].Text = file.FirstName;
                item.SubItems[2].Text = file.LastName;
                item.SubItems[3].Text = file.LastWriteTime.ToString("yyyy-MM-dd hh:mm");
            }
            else if (item.Tag is ClothesFile) {
                ClothesFile file = item.Tag as ClothesFile;
                item.Text = file.Name;
                item.SubItems[2].Text = file.LastWriteTime.ToString("yyyy-MM-dd hh:mm");
            }
        }

        private void btnEdit_Click(object sender, EventArgs e) {
            ((AI3File)propertyGrid.SelectedObject).Save();
            UpdateListViewItem(listView.SelectedItems[0]);
            Program.Message("保存成功");
        }

        private void lvGirls_SelectedIndexChanged(object sender, EventArgs e) {
            if (lvGirls.SelectedItems.Count > 0) {
                pgGirl.SelectedObject = lvGirls.SelectedItems[0].Tag;
                string priviewFile = PathHelper.Combine(saveFolder, "m_cha", lvGirls.SelectedItems[0].Text + "_v.bmp");

                priviewGirl.Image = File.Exists(priviewFile) ? Image.FromFile(priviewFile) : global::AI3SaveEditor.Properties.Resources.no_priview;
            }
        }

        private void lvClothes_SelectedIndexChanged(object sender, EventArgs e) {
            if (lvClothes.SelectedItems.Count > 0) {
                ClothesFile file = lvClothes.SelectedItems[0].Tag as ClothesFile;
                pgClothes.SelectedObject = file;
                string priviewFile = PathHelper.Combine(saveFolder, "m_cos", Path.GetFileNameWithoutExtension(file.FileName) + "_v.bmp");
                if (priviewClothes.Image != null) {
                    priviewClothes.Image.Dispose();
                }
                if (File.Exists(priviewFile)) {
                    File.Copy(priviewFile, Path.Combine(Application.StartupPath, "priview-clothes.bmp"), true);
                }
                priviewClothes.Image = File.Exists(priviewFile) ? Image.FromFile(Path.Combine(Application.StartupPath, "priview-clothes.bmp")) : global::AI3SaveEditor.Properties.Resources.no_priview;
            }
        }

        private void cboViewType_SelectedIndexChanged(object sender, EventArgs e) {
            this.listView.View = (View)cboViewType.SelectedItem;
        }

        private void tabControl_SelectedIndexChanged(object sender, EventArgs e) {
            RefreshInfos();
        }

        private void RefreshInfos() {
            lbStatus.Text = string.Format("共{0}个", this.listView.Items.Count);
            cboViewType.Text = this.listView.View.ToString();
        }

        private void btnRefresh_Click(object sender, EventArgs e) {
            if (tabControl.SelectedTab == tbGirls)
                RefreshGirls();
            else if (tabControl.SelectedTab == tbClothes)
                RefreshClothes();
            RefreshInfos();
        }

        private void iChangeNames_Click(object sender, EventArgs e) {
            if (lvClothes.SelectedItems.Count > 0)
                new ClothesNamesEditor(GetClothesFiles(), lvClothes.Items).ShowDialog();
            RefreshClothesNames();
        }

        private void RefreshClothesNames() {
            foreach (ListViewItem each in lvClothes.Items) {
                ClothesFile file = each.Tag as ClothesFile;
                each.Text = file.Name;
            }
        }

        private IEnumerable<ClothesFile> GetClothesFiles() {
            foreach (ListViewItem each in lvClothes.SelectedItems) {
                yield return each.Tag as ClothesFile;
            }
        }

        private void btnTest_Click(object sender, EventArgs e) {
            //255,121,181
            string cmiFile = @"F:\Games\Illusion\AI3\Game\data\SAVE\M_CHA\TEST01.js3cmi";
            string csiFile = @"F:\Games\Illusion\AI3\Game\data\SAVE\M_CHA\TEST01\TEST01.js3csi";
            //GirlProfile girl = (GirlProfile)GirlProfile.Load(@"F:\Games\Illusion\AI3\Game\data\SAVE\M_CHA\TEST6.js3cmi");

            byte[] cmi = IllusionUtils.CMIDecrypt.DecryptFile(cmiFile);
            byte[] csi = IllusionUtils.CMIDecrypt.DecryptFile(csiFile);

            //bool equal = csi[942] == cmi[134] && csi[941] == cmi[136] && csi[940] == cmi[138];

            //MessageBox.Show(equal.ToString());

            //byte[] test = File.ReadAllBytes(@"F:\Games\illusion\人工少女3\data\SAVE\M_CHA\TEST\Test.pp");
            //byte[] test1 = File.ReadAllBytes(@"F:\Games\illusion\人工少女3\data\SAVE\M_CHA\TEST1\test1.pp");
            //BytesEquals(test, test1);

            //            {GirlProfileProperties.EyebrowColor_R,942},
            //{GirlProfileProperties.EyebrowColor_G,941},
            //{GirlProfileProperties.EyebrowColor_B,940},

            for (int i = 0; i < csi.Length; i++) {
                if (csi[i] == 181 && csi[i + 1] == 121 && csi[i+2] == 255) {
                    MessageBox.Show(i.ToString());
                }
            }

            //test = IllusionUtils.CMIDecrypt.DecryptFile(@"F:\Games\illusion\人工少女3\data\SAVE\M_CHA\TEST\TEST.js3csi");
            //test1 = IllusionUtils.CMIDecrypt.DecryptFile(@"F:\Games\illusion\人工少女3\data\SAVE\M_CHA\TEST1\TEST1.js3csi");
            //BytesEquals(test, test1);

            //DecryptUtil.DecryptFile(@"F:\Games\illusion\人工少女3\data\js3_00_01_HM.pp");

            //BytesEquals(test, test1);
            //BytesEquals(test, test1);
        }

        private bool BytesEquals(byte[] byte1, byte[] byte2) {
            if (byte1.Length != byte2.Length)
                return false;

            for (int i = 0; i < byte1.Length; i++) {
                if (byte1[i] != byte2[i]) {
                    MessageBox.Show(i.ToString());
                    return false;
                }
            }
            return true;
        }

        private void iChangeClothesSetting_Click(object sender, EventArgs e) {
            if (lvGirls.SelectedItems.Count == 0)
                return;
            SettingClothes(lvGirls.SelectedItems[0].Tag as GirlProfile);
        }

        private void SettingClothes(GirlProfile girlProfile) {
            new ClothesSettingEditor(girlProfile, this.lvClothes).ShowDialog();
            pnlClothes.Controls.Add(this.lvClothes);
        }

        private void btnChangeClothesFileName_Click(object sender, EventArgs e) {
            if (lvClothes.SelectedItems.Count == 0) {
                Program.Message("请选择衣服");
                return;
            }
            ClothesFile file = lvClothes.SelectedItems[0].Tag as ClothesFile;
            file.ChangeFileNameToClothesName();
        }
    }
}
